/***************************************************************************************************
  *Copyright(C),2010-2016,Sumscope
  *FileName	:  string_aes.cpp
  *Author	:  scofined.qi
  *Version	:  1.0
  *Date		:  2017/04/19
  *Desc		:  //用于主要说明此程序文件完成的主要功能
  *Relation :  
  *Others	:  //其他内容说明
  *Function :  //主要函数列表，每条记录应包含函数名及功能简要说明
  *History	:  //修改历史记录列表，每条修改记录应包含修改日期、修改者及修改内容简介
***************************************************************************************************/
#include "string_aes.h"
//#include "./minizip/mzaes.h"
#include <string.h>
#include <string>

//using namespace std;
#pragma warning( disable : 4996)
#define PARAM_ERROR -1


#define CHECK_LOG(format,...)	\
    if (false){BLOGERR(format,##__VA_ARGS__);}

namespace qb{
	namespace base{
		namespace{

#define MOD8(a)	(a-((a>>3)<<3))
#define SWAP4(a, b) *(int*)(a) = (*(int*)(a)) ^ (*(int*)(b));	\
				*((int*)(b))=(*(int*)(b))^(*(int*)(a));			\
				*((int*)(a))=(*(int*)(a))^(*(int*)(b));
#define SWAP8(a,b)	SWAP4(a, b);SWAP4((char*)a+4, (char*)b+4);
#define SWAP16(a,b)	SWAP8(a, b);SWAP8((char*)a+8, (char*)b+8);
#define SWAP32(a,b)	SWAP16(a, b);SWAP16((char*)a+16, (char*)b+16);


#define COPY8(DEST,SOURCE)	*((double*)(DEST))=*((const double*)(SOURCE));

#define COPY16(DEST,SOURCE)	*((double*)(DEST))=*((const double*)(SOURCE));	\
			*((double*)(DEST) + 1) = *((const double*)(SOURCE) + 1);	

#define COPY32(DEST,SOURCE) *((double*)(DEST))=*((const double*)(SOURCE));	\
			*((double*)(DEST) + 1) = *((const double*)(SOURCE) + 1);		\
			*((double*)(DEST) + 2) = *((const double*)(SOURCE) + 2);		\
			*((double*)(DEST) + 3) = *((const double*)(SOURCE) + 3);		

#define COPY48(DEST,SOURCE) *((double*)(DEST))=*((const double*)(SOURCE));	\
			*((double*)(DEST) + 1) = *((const double*)(SOURCE) + 1);		\
			*((double*)(DEST) + 2) = *((const double*)(SOURCE) + 2);		\
			*((double*)(DEST) + 3) = *((const double*)(SOURCE) + 3);		\
			*((double*)(DEST) + 4) = *((const double*)(SOURCE) + 4);		\
			*((double*)(DEST) + 5) = *((const double*)(SOURCE) + 5);		

#define COPY64(DEST,SOURCE) *((double*)(DEST))=*((const double*)(SOURCE));	\
			*((double*)(DEST) + 1) = *((const double*)(SOURCE) + 1);		\
			*((double*)(DEST) + 2) = *((const double*)(SOURCE) + 2);		\
			*((double*)(DEST) + 3) = *((const double*)(SOURCE) + 3);		\
			*((double*)(DEST) + 4) = *((const double*)(SOURCE) + 4);		\
			*((double*)(DEST) + 5) = *((const double*)(SOURCE) + 5);		\
			*((double*)(DEST) + 6) = *((const double*)(SOURCE) + 6);		\
			*((double*)(DEST) + 7) = *((const double*)(SOURCE) + 7);

			///////////////////////////////////////////////////////////////////////////
			///////////////////////////////////////////////////////////////////////////
			/*初始置换表IP*/
			const int IP_Table[64] = { 57, 49, 41, 33, 25, 17, 9, 1,
				59, 51, 43, 35, 27, 19, 11, 3,
				61, 53, 45, 37, 29, 21, 13, 5,
				63, 55, 47, 39, 31, 23, 15, 7,
				56, 48, 40, 32, 24, 16, 8, 0,
				58, 50, 42, 34, 26, 18, 10, 2,
				60, 52, 44, 36, 28, 20, 12, 4,
				62, 54, 46, 38, 30, 22, 14, 6 };
			/*逆初始置换表IP^-1*/
			const int IP_1_Table[64] = { 39, 7, 47, 15, 55, 23, 63, 31,
				38, 6, 46, 14, 54, 22, 62, 30,
				37, 5, 45, 13, 53, 21, 61, 29,
				36, 4, 44, 12, 52, 20, 60, 28,
				35, 3, 43, 11, 51, 19, 59, 27,
				34, 2, 42, 10, 50, 18, 58, 26,
				33, 1, 41, 9, 49, 17, 57, 25,
				32, 0, 40, 8, 48, 16, 56, 24 };
			/*扩充置换表E*/
			const int E_Table[48] = { 31, 0, 1, 2, 3, 4,
				3, 4, 5, 6, 7, 8,
				7, 8, 9, 10, 11, 12,
				11, 12, 13, 14, 15, 16,
				15, 16, 17, 18, 19, 20,
				19, 20, 21, 22, 23, 24,
				23, 24, 25, 26, 27, 28,
				27, 28, 29, 30, 31, 0 };
			/*置换函数P*/
			const int P_Table[32] = { 15, 6, 19, 20, 28, 11, 27, 16,
				0, 14, 22, 25, 4, 17, 30, 9,
				1, 7, 23, 13, 31, 26, 2, 8,
				18, 12, 29, 5, 21, 10, 3, 24 };
			/*S盒*/
			const int S[8][4][16] =
				/*S1*/
			{ { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 },
			{ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 },
			{ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 },
			{ 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 } },
			/*S2*/
			{ { 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 },
			{ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 },
			{ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 },
			{ 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 } },
			/*S3*/
			{ { 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 },
			{ 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 },
			{ 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 },
			{ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 } },
			/*S4*/
			{ { 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 },
			{ 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 },
			{ 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 },
			{ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 } },
			/*S5*/
			{ { 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 },
			{ 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 },
			{ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 },
			{ 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 } },
			/*S6*/
			{ { 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 },
			{ 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 },
			{ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 },
			{ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 } },
			/*S7*/
			{ { 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 },
			{ 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 },
			{ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 },
			{ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 } },
			/*S8*/
			{ { 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 },
			{ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 },
			{ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 },
			{ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 } } };
			/*置换选择1*/
			const int PC_1[56] = { 56, 48, 40, 32, 24, 16, 8,
				0, 57, 49, 41, 33, 25, 17,
				9, 1, 58, 50, 42, 34, 26,
				18, 10, 2, 59, 51, 43, 35,
				62, 54, 46, 38, 30, 22, 14,
				6, 61, 53, 45, 37, 29, 21,
				13, 5, 60, 52, 44, 36, 28,
				20, 12, 4, 27, 19, 11, 3 };
			/*置换选择2*/
			const int PC_2[48] = { 13, 16, 10, 23, 0, 4, 2, 27,
				14, 5, 20, 9, 22, 18, 11, 3,
				25, 7, 15, 6, 26, 19, 12, 1,
				40, 51, 30, 36, 46, 54, 29, 39,
				50, 44, 32, 46, 43, 48, 38, 55,
				33, 52, 45, 41, 49, 35, 28, 31 };
			/*对左移次数的规定*/
			const int MOVE_TIMES[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };

			//////////////////////////////////////////////////////////////////////////

			/*字节转换成二进制*/
            void ByteToBit(char ch, char bit[8])
			{
				for (int cnt = 0; cnt < 8; cnt++)
				{
					*(bit + cnt) = (ch >> cnt) & 1;
				}
			}
			/*二进制转换成字节*/
            void BitToByte(char bit[8], char *ch)
			{
				for (int cnt = 0; cnt < 8; cnt++)
				{
					*ch |= *(bit + cnt) << cnt;
				}
			}
			/*将长度为8的字符串转为二进制位串*/
            int Char8ToBit64(char ch[8], char bit[64])
			{
				for (int cnt = 0; cnt < 8; cnt++)
				{
					ByteToBit(*(ch + cnt), bit + (cnt << 3));
				}
				return 0;
			}
			/*将二进制位串转为长度为8的字符串*/
            int Bit64ToChar8(char bit[64], char ch[8])
			{
				int cnt = 0;
				memset(ch, 0, 8);
				for (cnt = 0; cnt < 8; cnt++)
				{
					BitToByte(bit + (cnt << 3), ch + cnt);
				}
				return 0;
			}

			/*密钥置换1*/
            void DES_PC1_Transform(char key[64], char tempbts[56])
			{
				for (int cnt = 0; cnt < 56; cnt++)
					tempbts[cnt] = key[PC_1[cnt]];
			}
			/*密钥置换2*/
            void DES_PC2_Transform(char* key/*[56]*/, char* tempbts/*[48]*/)
			{
				for (int cnt = 0; cnt < 48; cnt++)
					tempbts[cnt] = key[PC_2[cnt]];
			}
			/*循环左移
			  原始的代码存在bug:time只能为1或者2,
				memcpy(data, data + time, 28 - time);
				此时两个参数内存重叠
			
			*/
			int DES_ROL(char data[56], int time)
			{
				if ((data == NULL) || (time < 0))
				{
					return PARAM_ERROR;
				}
				char temp[56] = { 0 };
				/*保存将要循环移动到右边的位*/
				memcpy(temp, data, time);
				memcpy(temp + time, data + 28, time);
				/*前28位移动*/
				memcpy(data, data + time, 28 - time);
				memcpy(data + 28 - time, temp, time);
				/*后28位移动*/
				memcpy(data + 28, data + 28 + time, 28 - time);
				memcpy(data + 56 - time, temp + time, time);
				return 0;
			}
            void ROL28_1(char data[28])
			{
				char c = data[0];
				for (int i = 0; i < 27; i++)
					data[i] = data[i + 1];
				data[27] = c;
			}
            void ROL28_2(char data[28])
			{
				char c = data[0], c2 = data[1];
				for (int i = 2; i < 28; i++)
					data[i-2] = data[i];
				data[26] = c; data[27] = c2;
			}

			/*生成子密钥*/
			void DES_MakeSubKeys(char* key/*[64]*/, char subKeys[16][48])
			{
				char stemp56[56] = { 0 };
				memset(stemp56, 0, 56);
				DES_PC1_Transform(key, stemp56);/*PC1置换*/
				for (int cnt = 0; cnt < 16; cnt++)
				{
					/*16轮跌代，产生16个子密钥*/
					//DES_ROL(stemp56, MOVE_TIMES[cnt]);
					if (1 == MOVE_TIMES[cnt]){ ROL28_1(stemp56); ROL28_1(stemp56+28); }
					else{ ROL28_2(stemp56); ROL28_2(stemp56 + 28); }
					/*循环左移*/
					DES_PC2_Transform(stemp56, subKeys[cnt]);/*PC2置换，产生子密钥*/
				}
			}
			/*IP置换*/
            void DES_IP_Transform(char* data)
			{
				char stemp64[64] = { 0 };
				for (int cnt = 0; cnt < 64; cnt++)
					stemp64[cnt] = data[IP_Table[cnt]];
				COPY64(data, stemp64);
			}
			/*IP逆置换*/
            void DES_IP_1_Transform(char data[64])
			{
				char stemp64[64] = { 0 };
				for (int cnt = 0; cnt < 64; cnt++)
					stemp64[cnt] = data[IP_1_Table[cnt]];
				COPY64(data, stemp64);
			}
			/*扩展置换*/
            void DES_E_Transform(char data[48])
			{
				char stemp48[48] = { 0 };
				for (int cnt = 0; cnt < 48; cnt++)
					stemp48[cnt] = data[E_Table[cnt]];
				COPY48(data, stemp48);
			}
			/*P置换*/
            void  DES_P_Transform(char data[32])
			{
				char temp[32] = { 0 };
				for (int cnt = 0; cnt < 32; cnt++)
					temp[cnt] = data[P_Table[cnt]];
				COPY32(data, temp);
			}
			/*异或*/
            void  DES_XOR(char* R/*[48]*/, char* L/*[48]*/, int count)
			{
				for (int cnt = 0; cnt < count; cnt++, R++, L++)
					*R ^= *L;
			}
			/*S盒置换*/
            void DES_SBOX(char data[48])
			{
				int cnt = 0;
				int line = 0;
				int row = 0;
				int output = 0;
				int cur1 = 0, cur2 = 0;
				for (cnt = 0; cnt < 8; cnt++)
				{
					cur1 = cnt * 6;
					cur2 = cnt << 2;
					/*计算在S盒中的行与列*/
					line = (data[cur1] << 1) + data[cur1 + 5];
					row = (data[cur1 + 1] << 3) + (data[cur1 + 2] << 2) + (data[cur1 + 3] << 1) + data[cur1 + 4];
					output = S[cnt][line][row];
					/*化为2进制*/
					data[cur2] = (output & 0X08) >> 3;
					data[cur2 + 1] = (output & 0X04) >> 2;
					data[cur2 + 2] = (output & 0X02) >> 1;
					data[cur2 + 3] = output & 0x01;
				}
			}
			/*交换*/
			void DES_Swap(char left[32], char right[32])
			{
				SWAP32(left, right);
				//char temp[32] = { 0 };
				//COPY32(temp, left);
				//COPY32(left, right);
				//COPY32(right, temp);
			}
			
			/*加密单个分组*/
			int DES_EncryptBlock(char* plainBlock/*[8]*/, char subKeys[16][48], char* cipherBlock/*[8]*/)
			{
				char plainBits[64] = { 0 };
				char copyRight[48] = { 0 };
				if ((plainBlock == NULL) || (subKeys == NULL) || (cipherBlock == NULL))
				{
					return PARAM_ERROR;
				}
				memset(plainBits, 0, 64);
				memset(copyRight, 0, 48);
				int cnt = 0;
				Char8ToBit64(plainBlock, plainBits);
				/*初始置换（IP置换）*/
				DES_IP_Transform(plainBits);
				/*16轮迭代*/
				for (cnt = 0; cnt < 16; cnt++)
				{
					COPY32(copyRight, plainBits + 32);
					/*将右半部分进行扩展置换，从32位扩展到48位*/
					DES_E_Transform(copyRight);
					/*将右半部分与子密钥进行异或操作*/
					DES_XOR(copyRight, subKeys[cnt], 48);
					/*异或结果进入S盒，输出32位结果*/
					DES_SBOX(copyRight);
					/*P置换*/
					DES_P_Transform(copyRight);
					/*将明文左半部分与右半部分进行异或*/
					DES_XOR(plainBits, copyRight, 32);
					if (cnt != 15)
					{
						/*最终完成左右部的交换*/
						DES_Swap(plainBits, plainBits + 32);
					}
				}
				/*逆初始置换（IP^1置换）*/
				DES_IP_1_Transform(plainBits);
				Bit64ToChar8(plainBits, cipherBlock);
				return 0;
			}
			/*解密单个分组*/
			int DES_DecryptBlock(char* cipherBlock/*[8]*/, char subKeys[16][48], char* plainBlock/*[8]*/)
			{
				char plainBits[64] = { 0 };
				char copyRight[48] = { 0 };
				if ((plainBlock == NULL) || (subKeys == NULL) || (cipherBlock == NULL))
				{
					return PARAM_ERROR;
				}
				memset(plainBits, 0, 64);
				memset(copyRight, 0, 48);
				int cnt = 0;

				Char8ToBit64(cipherBlock, plainBits);
				/*初始置换（IP置换）*/
				DES_IP_Transform(plainBits);

				/*16轮迭代*/
				for (cnt = 15; cnt >= 0; cnt--)
				{
					COPY32(copyRight, plainBits + 32);
					/*将右半部分进行扩展置换，从32位扩展到48位*/
					DES_E_Transform(copyRight);
					/*将右半部分与子密钥进行异或操作*/
					DES_XOR(copyRight, subKeys[cnt], 48);
					/*异或结果进入S盒，输出32位结果*/
					DES_SBOX(copyRight);
					/*P置换*/
					DES_P_Transform(copyRight);
					/*将明文左半部分与右半部分进行异或*/
					DES_XOR(plainBits, copyRight, 32);
					if (cnt != 0)
					{
						/*最终完成左右部的交换*/
						DES_Swap(plainBits, plainBits + 32);
					}
				}

				/*逆初始置换（IP^1置换）*/
				DES_IP_1_Transform(plainBits);
				Bit64ToChar8(plainBits, plainBlock);
				return 0;
			}

		}
		StringAes::StringAes(const char* tag)
		{
			memset(bKey, 0, 64);
			for (int i = 0; i < 16;i++)
				memset(subKeys[i], 0,48);

			SetTag(tag);
		}
		void StringAes::SetTag(const char* tag)
		{
			memset(keyBlock, 0, 16);
			COPY8(keyBlock, tag);/*设置密钥*/
			Char8ToBit64(keyBlock, bKey);/*将密钥转换为二进制流*/
			DES_MakeSubKeys(bKey, subKeys);/*生成子密钥*/
		}
		int StringAes::Encrypt(const char * pszInText, int insize, char* dataencrypted, int outsize)
		{
			if (pszInText == NULL || insize <= 0 || dataencrypted == NULL)
				return false;
			if (insize > outsize || MOD8(outsize)!= 0)
				return 0;

			memcpy(dataencrypted, pszInText, insize);
			if (outsize > insize)
				memset(dataencrypted + insize, 0, outsize - insize);
			return EncryptInPlace(dataencrypted, insize, outsize);
		}
		int StringAes::Decrypt(const char * pszInText, int insize, char* datadecrypted, int outsize)
		{
			/*
			将长度为insize的数据pszInText进行解码
			条件:insize必须是8的整数倍,outsize必须>insize
			返回:<=insize
			*/
			if (pszInText == NULL || insize <= 0 || datadecrypted == NULL || outsize <= 0)
				return false;
			
			if (MOD8(insize)!= 0 || outsize < insize)
				return 0;
			memcpy(datadecrypted, pszInText, insize);
			if (outsize > insize)
				memset(datadecrypted + insize, 0, outsize - insize);
			return DecryptInPlace(datadecrypted, insize, outsize);
		}
		int StringAes::EncryptInPlace(char* buf, int size, int capcity)
		{
			if (buf == 0 || size <= 0 || size > capcity || MOD8(capcity) != 0)
			{
				return 0;
			}
			int nloop = size>>3;
			int ntail = size - (nloop<<3);
			char plainBlock[9] = { 0 };
			char cipherBlock[9] = { 0 };

			char *pch = buf;
			const char *pchEnd = buf + (nloop<<3);
			for (; pch < pchEnd; pch += 8)
			{
				COPY8(plainBlock, pch);
				DES_EncryptBlock(plainBlock, subKeys, cipherBlock);
				COPY8(pch, cipherBlock);
			}

			// 最后不足8个字节,以0填充,最后一个以实际长度填充,加密后的长度永远都是8的整数倍
			if (ntail > 0)
				memcpy(plainBlock, pch, ntail);
			memset(plainBlock + ntail, '\0', 7 - ntail);
			plainBlock[7] = ntail;
			DES_EncryptBlock(plainBlock, subKeys, cipherBlock);
			COPY8(pch, cipherBlock);
			nloop++;
			return nloop<<3;
		}
		int StringAes::DecryptInPlace(char* buf, int size, int capcity)
		{
			/*
			将长度为insize的数据pszInText进行解码
			条件:insize必须是8的整数倍,outsize必须>insize
			返回:<=insize
			*/
			if (buf == 0 || size <= 0 || size > capcity || MOD8(size) != 0)
			{
				return 0;
			}

			int nloop = size>>3;
			int ntail = size - (nloop<<3);
			if (ntail != 0)
			{
				return 0;
			}
				
			char plainBlock[9] = { 0 };
			char cipherBlock[9] = { 0 };
			char *pch = buf;
			const char *pchEnd = buf + (nloop<<3);
			for (; pch < pchEnd; pch += 8)
			{
				COPY8(cipherBlock, pch);
				DES_DecryptBlock(cipherBlock, subKeys, plainBlock);
				COPY8(pch, plainBlock);
			}
			ntail = plainBlock[7];//原始最末位8个字节的实际数据长度
			if (ntail >= 8 || ntail < 0)
			{
				return 0;
			}
			pch -= 8;
			memset(pch + ntail, 0, 8 - ntail);
			return size - 8 + ntail;
		}

		int Encrypt(const char * pszInText, int insize, char* dataencrypted, int outsize, const char* key)
		{
			StringAes ae(key);
			return ae.Encrypt(pszInText, insize, dataencrypted, outsize);
		}
		int Decrypt(const char * pszInText, int insize, char* datadecrypted, int outsize, const char* key)
		{
			StringAes ae(key);
			return ae.Decrypt(pszInText, insize, datadecrypted, outsize);
		}
		//////////////////////////////////////////////////////////////////////////
		typedef const unsigned char* lpcustr;
		typedef unsigned char* lpustr;
		class AesCoderImpl {
        //	aes_encrypt_ctx	m_encrypt[1];
        //	aes_decrypt_ctx	m_decrypt[1];
		public:
			AesCoderImpl(lpcustr key)
			{
				SetKey(key);
			}
			void SetKey(const unsigned char* key)
			{
				unsigned char keyblock[130] = { 0 };
				memset(keyblock, 0, 130);
				#if WIN32
				strncpy_s((char*)keyblock, 130, (const char*)key, -1);
				#else
				strncpy((char*)keyblock,(const char*)key, 130);
				if(keyblock[129] != '\0')
					keyblock[129] = '\0';
				#endif
//				aes_encrypt_key128(keyblock, m_encrypt);
//				aes_decrypt_key128(keyblock, m_decrypt);
			}
			int Encrypt(const char * pszInText, int insize, char* dataencrypted, int outsize)
			{
				int nloop = insize >> 4;
				int ntail = insize - (nloop << 4);
				const unsigned char* source = (const unsigned char*)pszInText;
				unsigned char* dest = (unsigned char*)dataencrypted;
				const unsigned char* send = source + (insize - ntail);
				unsigned char padding[16] = { 0 };
				bool equal = false;
				for (; source < send; source += 16, dest += 16)
				{
//					aes_encrypt(source, dest, m_encrypt);
				}
				if (ntail > 0)memcpy(padding, source, ntail);
				memset(padding + ntail, 0, 16 - ntail);
				padding[15] = ntail;
//				aes_encrypt(padding, dest, m_encrypt);
				return (nloop << 4) + 16;
			}
			int Decrypt(const char * pszInText, int insize, char* datadecrypted, int outsize)
			{
				int nloop = insize >> 4;
				int ntail = insize - (nloop << 4);
				const unsigned char* source = (const unsigned char*)pszInText;
				unsigned char* dest = (unsigned char*)datadecrypted;
				const unsigned char* send = source + (insize - ntail);
				for (; source < send; source += 16, dest += 16)
				{
//					aes_decrypt(source, dest, m_decrypt);
				}
				dest -= 16;
				ntail = dest[15];
				if (ntail >= 16 || ntail < 0)
					return 0;
				memset(dest + ntail, 0, 16 - ntail);
				return insize - 16 + ntail;
			}
		};
		BlockAes::BlockAes(const char* tag)
		{
			m_impl = new AesCoderImpl((lpcustr)tag);
		}
		BlockAes::~BlockAes()
		{
			if (m_impl)
				delete m_impl;
		}
		void BlockAes::SetTag(const char* tag)
		{
			m_impl->SetKey((const unsigned char*)tag);
		}
		int BlockAes::Encrypt(const char * pszInText, int insize, char* dataencrypted, int outsize)
		{
			return m_impl->Encrypt(pszInText, insize, dataencrypted, outsize);
		}
		int BlockAes::Decrypt(const char * pszInText, int insize, char* datadecrypted, int outsize)
		{
			return m_impl->Decrypt(pszInText, insize, datadecrypted, outsize);
		}
	}
}
